package se.webbzon.boltzmann.world;

import java.util.Collection;

import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.boltzmann.environment.PlayerEnvironment;
import se.webbzon.boltzmann.game.object.camera.GameCamera;
import se.webbzon.boltzmann.hud.BlackOverlay;
import se.webbzon.boltzmann.object.cinema.CameraNode;
import se.webbzon.boltzmann.object.cinema.AbstractCinemaTerminator;
import se.webbzon.boltzmann.object.escaper.DefaultEscaper;
import se.webbzon.boltzmann.player.Player;
import se.webbzon.oschi01.worldarea.WorldArea;

public class CinemaWorldLoader extends AbstractWorldLoader {
	
	// The cinema terminator associated with this cinema world
	private final AbstractCinemaTerminator terminator;

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new cinema world loader. **/
	public CinemaWorldLoader(AbstractEnvironment env, String worldAreaName, AbstractCinemaTerminator terminator) {
		super(env, worldAreaName);
		this.terminator = terminator;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public WorldArea load() throws WorldLoaderException {
		WorldArea world = super.load();
		
		// Add an escaper to the world
		world.createInstance(new DefaultEscaper());
		
		// Add a black overlay
		world.createInstance(new BlackOverlay());
		
		world.createInstance(terminator);
		AbstractEnvironment env = getEnvironment();
		if (env instanceof PlayerEnvironment) {
			PlayerEnvironment penv = (PlayerEnvironment) env;
			Collection<CameraNode> nodes = world.findInstances(CameraNode.class);
			CameraNode node = nodes.isEmpty() ? null : nodes.iterator().next();
			Collection<Player> players = penv.getPlayers();
			synchronized (players) {
				for (Player player : players) {
					GameCamera camera = new GameCamera(player);
					camera.addView(player.getView());
					if (node != null)
						camera.setTarget(node);
					camera.snap();
					world.createInstance(camera);
				}
			}
		}
		return world;
	}

}
